package com.example.administrator.qq;

import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.media.AudioAttributes;
import android.media.AudioManager;
import android.media.SoundPool;
import android.os.Build;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;
import android.view.Gravity;
import android.view.View;
import android.os.Handler;
import android.os.Message;
import android.widget.Toast;

import com.example.administrator.DB.DBManager;
import com.example.administrator.VO.Point;
import com.example.administrator.VO.UserInfo;
import com.example.administrator.VO.UserPoint;


import java.util.Timer;
import java.util.TimerTask;

public class Game2Activity extends AppCompatActivity {

    //首先布局
    //64个ImageButton代表64个色块
    ImageButton[] btn = new ImageButton[64];
    //利用map二位数组记录各个色块的逻辑位置
    private int map[][] = new int[8][8];
    //利用随机生成的num，对应相应的图片
    private int num;
    //对应相应的图片，不懂的id值代表不同的图片
    private int id;
    //记录是否可以消除和更新成什么
    private int mark[][] = new int[8][8];
    //初始化点
    private Point p1 = new Point(-2, -2);
    private Point p2 = new Point(-2, -2);
    //用于选择按的色块
    private boolean isPoint = true;
    //获得的分数，消除一个色块得到5分
    private static int score = 0;

    //用于记录步数
    private int step ;
    //初始步数
    private static final int START_STEP = 30;

    //初始分数
    private static final int START_SCORE = 0;
    //用于显示游戏剩余步数
    private TextView stepText;
    //数据库连接
    private DBManager dbManager;
    //用于暂停游戏
    private Button button;

    //声明一个SoundPool
    private SoundPool mySoundPool;
    //定义一个整型用load（）；来设置suondID
    private int buttonMusic;
    private int boomMusic;
    private int gameoverMusic;
    //判断位是否找到
    private boolean isFind = false;




    //用于显示分数
    private TextView text;

    //用于显示倒计时对话框
    private Dialog myDialog ;
    private Timer myTimer;
    private TextView myTextView;
    private Handler clockHandler;
    //传递switch语句的六种情况
    private static final int BLOCK_BOOM = 0;
    private static final int BLOCK_UPDATE = 1;
    private static final int BLOCK_EXCHANGE = 2;
    private static final int BLOCK_REFRESH = 3;
    private static final int STEP_UPDATE = 4;
    private static final int STEP_OVER = 5;
    private static  final int BLOCK_RESTORE = 6;

    //构造函数
    public Game2Activity() {
    }
    //    获得随机团案
    private int getStyle() {
        num = (int) (1 + Math.random() * (6));
        switch (num) {
            case 1:
                return id = R.mipmap.block10;
            case 2:
                return id = R.mipmap.block20;
            case 3:
                return id = R.mipmap.block30;
            case 4:
                return id = R.mipmap.block40;
            case 5:
                return id = R.mipmap.block50;
            case 6:
                return id = R.mipmap.block60;
//            case 7:
//                return id = R.mipmap.www;
            default:
                return id = 0;
        }
    }
    //初始化色块
    private void initBtn(int i, int j) {
        btn[8 * i + j].setImageResource(getStyle());
        Point p = new Point(i, j, btn[8 * i + j], id);
        btn[8 * i + j].setTag(p);
        map[i][j] = num;
    }
    //重写onCreate方法

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_game2);
        dbManager = new DBManager(this);
        //android 的用户界面一般使用xml文件做的，对应的xml文件在layout包下
        //如果xml里放了个按钮什么的，在activity中要获取该按钮就用findViewById(R.id.xml文件中对应的id)
        LinearLayout vlayout = (LinearLayout) findViewById(R.id.vlayout);
        //TableLayout和TableRow配合使用
        TableLayout tlayout = new TableLayout(this);
        TableRow row[] = new TableRow[8];
        for (int i = 0; i < 8; i++) {
            row[i] = new TableRow(this);
            //android:gravity 是设置该view里面的内容相对于该view的位置,居中
            row[i].setGravity(Gravity.CENTER);
            for (int j = 0; j < 8; j++) {
                btn[8 * i + j] = new ImageButton(this);
                //设置色块的大小
                btn[8 * i + j].setLayoutParams(new TableRow.LayoutParams(135, 135));
                initBtn(i, j);
                btn[8 * i + j].setOnClickListener(listener);
                row[i].addView(btn[8 * i + j]);
            }
            tlayout.addView(row[i]);

        }

        text = new TextView(this);
        stepText = new TextView(this);
        myTextView = new TextView(this);
        button = new Button(this);
        //保证第一次显示的色块中无可消除的
        while (find()) {
            updateState();
        }


        stepText.setTextSize(20);
        myTextView.setGravity(Gravity.CENTER_HORIZONTAL);
        myTextView.setTextSize(20);
        button.setText("退出游戏");
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //暂停计时
                new AlertDialog.Builder(Game2Activity.this).
                        setTitle("确定要退出游戏吗？")
                        .setMessage("当前得分："+score)
                        .setCancelable(false)
                        .setPositiveButton("退出游戏",new DialogInterface.OnClickListener(){
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                Intent i = new Intent(Game2Activity.this,ModelActivity.class);
                                startActivity(i);
                                Game2Activity.this.finish();
                            }})
                        .setNegativeButton("继续游戏", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {

                            }
                        })
                        .show();
            }
        });
        //初始化得分
        score = START_SCORE;
        text.setText("分数:    "+START_SCORE);

        step = START_STEP;
        stepText.setText("剩余步数:    "+START_STEP);
        vlayout.addView(tlayout);
        vlayout.addView(button);
        vlayout.addView(text);
        vlayout.addView(stepText);
        initMusic();//初始化音效
        initDialog();//初始化倒计时框
    }
    //判断当前界面中是否存在可以消除的色块，存在可以消除的色块，返回tne
    private boolean find() {
        for (int i = 0; i < 8; i++) {
            for (int j = 0; j < 8; j++) {
                mark[i][j] = 0;
            }
        }
        //标志位，表示是否存在可以消除的色块
        boolean flag = false;
        //横向遍历寻找
        for (int i = 0; i < 8; i++) {
            int count = 1;
            for (int j = 0; j < 7; j++) {
                if (map[i][j] == map[i][j + 1]) {
                    count++;
                    if (count == 3) {
                        flag = true;
                        mark[i][j + 1] = 1;
                        mark[i][j] = 1;
                        mark[i][j - 1] = 1;
//                         score += 15;
                    } else if (count > 3) {
                        mark[i][j + 1] = 1;
//                          score += 5;
                    }
                } else {
                    count = 1;
                }
            }
        }
        //纵向遍历寻找
        for (int j = 0; j < 8; j++) {
            int count = 1;
            for (int i = 0; i < 7; i++) {
                if (map[i][j] == map[i + 1][j]) {
                    count++;
                    if (count == 3) {
                        flag = true;
//                        if(mark[i][j]==1) score+=10;
//                        else score += 15;
                        mark[i - 1][j] = 3;
                        mark[i][j] = 3;
                        mark[i + 1][j] = 3;
                        for (int k = i - 5; k >= 0; k--) {
                            mark[k][j] = 2;
                        }
                    } else if (count > 3) {
                        mark[i + 1][j] = count;
                        for (int k = 1; k < count; k++) {
                            mark[i - k + 1][j]++;
                        }

//                        if (i - 2 * count + 2 >= 0) mark[i - 2 * count + 2][j] = 0;
                        if (i == 6) mark[0][j] = 0;
//                        score += 5;
                    }
                } else count = 1;
            }
        }
        return flag;
    }
    //  延时函数
    private void wait1(int time) {
        try {
            Thread.sleep(time);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    //色块更新(无法从上方补充，即随机生成)
    private void updateBtn(int i, int j) {
        btn[8 * i + j].setImageResource(getStyle());
        map[i][j] = num;
        Point p = (Point) (btn[8 * i + j].getTag());
        p.setId(id);
        btn[8 * i + j].setTag(p);
        score += 5;
    }
    //色块更新（从上方补充）
    private void updateBtn(int x1, int y1, int x2, int y2) {
        map[x1][y1] = map[x2][y2];
        Point p = (Point) (btn[8 * x1 + y1].getTag());
        p.setId(((Point) (btn[8 * x2 + y2].getTag())).getId());
        btn[8 * x1 + y1].setTag(p);
        btn[8 * x1 + y1].setImageResource(p.getId());

    }
    //界面更新
    private void updateState() {
        for (int i = 7; i >= 0; i--) {
            for (int j = 7; j >= 0; j--) {
                if (mark[i][j] == 1) {
                    for (int k = i; k > 0; k--) {
                        updateBtn(k, j, k - 1, j);
                    }
                    updateBtn(0, j);
                } else if (mark[i][j] >= 3) {
//                    int s = mark[i][j];
//                    int s1 = i-s;
                    if(i-mark[i][j]>0){
                        updateBtn(i,j,i-mark[i][j],j);
                        if(i-mark[i][j]-mark[i][j]>0){
                            updateBtn(i-mark[i][j],j,i-mark[i][j]-mark[i][j],j);
                        }else{
                            updateBtn(i-mark[i][j],j);
                        }
                    }else updateBtn(i,j);
//                    int s2 = i-mark[i][j]-mark[i][j];

                }else if (mark[i][j] == 2) {
                    updateBtn(i, j);
//	                    score+=5;
                }

            }
        }
    }




    //呈现爆炸效果
    private void boomBtn() {
        mySoundPool.play(boomMusic, 1, 1, 0, 0, 1);
        for (int i = 0; i < 8; i++) {
            for (int j = 0; j < 8; j++) {
                if (mark[i][j] != 0 && mark[i][j] != 2) {
                    for (int k = 0; k < 9; k++) {
                        if (k < 3) btn[8 * i + j].setImageResource(R.mipmap.bomb_1);
                        if (k < 6) btn[8 * i + j].setImageResource(R.mipmap.bomb_2);
                        if (k < 9) btn[8 * i + j].setImageResource(R.mipmap.bomb_3);
//                        btn[8*i+j].getBackground().setAlpha(0);
                    }
                }
            }
        }
    }
    //将传入的某一个色块与四周的色块比较，看看能不能形成连续三个相同的,还存在可消除的返回true
    private boolean check(int i, int j) {
        //纵向比较
        int count = 1;
        if (i >= 1 && map[i - 1][j] == map[i][j]) {
            count++;
            if (i >= 2 && map[i - 2][j] == map[i][j]) {
                count++;
            }
        }
        if (count >= 3) return true;
        if (i + 1 < 8 && map[i + 1][j] == map[i][j]) {
            count++;
            if (i + 2 < 8 && map[i + 2][j] == map[i][j]) {
                count++;
            }
        }
        if (count >= 3) return true;

        //横向
        count = 1;
        if (j >= 1 && map[i][j - 1] == map[i][j]) {
            count++;
            if (j >= 2 && map[i][j - 2] == map[i][j]) {
                count++;
            }
        }

        if (j + 1 < 8 && map[i][j + 1] == map[i][j]) {
            count++;
            if (j + 2 < 8 && map[i][j + 2] == map[i][j]) {
                count++;
            }
        }
        if (count >= 3) return true;
        return false;
    }
    //模拟所有色块横竖交换，判断当前游戏是否能继续玩或者是需要重新更新64个色块，还存在可消除的返回true
    private boolean check() {
        //横向模拟
        for (int i = 0; i < 8; i++) {
            for (int j = 0; j < 7; j++) {
                swapMap(i, j, i, j + 1);
                if (check(i, j)) {
                    swapMap(i, j, i, j + 1);
                    return true;
                }
                if (check(i, j + 1)) {
                    swapMap(i, j, i, j + 1);
                    return true;
                }
                swapMap(i, j, i, j + 1);
            }
        }
        //纵向模拟
        for (int j = 0; j < 8; j++) {
            for (int i = 0; i < 7; i++) {
                swapMap(i, j, i + 1, j);
                if (check(i, j)) {
                    swapMap(i, j, i + 1, j);
                    return true;
                }
                if (check(i + 1, j)) {
                    swapMap(i, j, i + 1, j);
                    return true;
                }
                swapMap(i, j, i + 1, j);
            }
        }
        return false;
    }
    //交换2个色块的逻辑位置
    private void swapMap(int x1, int y1, int x2, int y2) {
        int tmp = map[x1][y1];
        map[x1][y1] = map[x2][y2];
        map[x2][y2] = tmp;
    }
    //交换2个色块团案
    void swapImage() {
        btn[p1.getX() * 8 + p1.getY()].setImageResource(p2.getId());
        btn[p2.getX() * 8 + p2.getY()].setImageResource(p1.getId());
        int tmp = p1.getId();
        p1.setId(p2.getId());
        p2.setId(tmp);
        btn[p1.getX() * 8 + p1.getY()].setTag(p1);
        btn[p2.getX() * 8 + p2.getY()].setTag(p2);
    }
    //点击后，色块带上金边，表示已经选中
    private void Selected(Point p) {
        switch (p.getId()) {
            case R.mipmap.block10: {
                btn[p.getX() * 8 + p.getY()].setImageResource(R.mipmap.block11);
                p.setId(R.mipmap.block11);
                break;
            }
            case R.mipmap.block20: {
                btn[p.getX() * 8 + p.getY()].setImageResource(R.mipmap.block21);
                p.setId(R.mipmap.block21);
                break;
            }
            case R.mipmap.block30: {
                btn[p.getX() * 8 + p.getY()].setImageResource(R.mipmap.block31);
                p.setId(R.mipmap.block31);
                break;
            }
            case R.mipmap.block40: {
                btn[p.getX() * 8 + p.getY()].setImageResource(R.mipmap.block41);
                p.setId(R.mipmap.block41);
                break;
            }
            case R.mipmap.block50: {
                btn[p.getX() * 8 + p.getY()].setImageResource(R.mipmap.block51);
                p.setId(R.mipmap.block51);
                break;
            }
            case R.mipmap.block60: {
                btn[p.getX() * 8 + p.getY()].setImageResource(R.mipmap.block61);
                p.setId(R.mipmap.block61);
                break;
            }
        }
    }
    //点击选中的色块，金边消失，表示没有选中
    private void unSelected(Point p) {
        switch (p.getId()) {
            case R.mipmap.block11: {
                btn[p.getX() * 8 + p.getY()].setImageResource(R.mipmap.block10);
                p.setId(R.mipmap.block10);
                break;
            }
            case R.mipmap.block21: {
                btn[p.getX() * 8 + p.getY()].setImageResource(R.mipmap.block20);
                p.setId(R.mipmap.block20);
                break;
            }
            case R.mipmap.block31: {
                btn[p.getX() * 8 + p.getY()].setImageResource(R.mipmap.block30);
                p.setId(R.mipmap.block30);
                break;
            }
            case R.mipmap.block41: {
                btn[p.getX() * 8 + p.getY()].setImageResource(R.mipmap.block40);
                p.setId(R.mipmap.block40);
                break;
            }
            case R.mipmap.block51: {
                btn[p.getX() * 8 + p.getY()].setImageResource(R.mipmap.block50);
                p.setId(R.mipmap.block50);
                break;
            }
            case R.mipmap.block61: {
                btn[p.getX() * 8 + p.getY()].setImageResource(R.mipmap.block60);
                p.setId(R.mipmap.block60);
                break;
            }
        }
    }
    //创建监听对象
    ImageButton.OnClickListener listener = new ImageButton.OnClickListener() {

        public void onClick(View v) {
            if (isPoint) {
                mySoundPool.play(buttonMusic, 1, 1, 0, 0, 1);
                p1 = (Point) v.getTag();
                Selected(p1);
                isPoint = false;
            } else {
                mySoundPool.play(buttonMusic, 1, 1, 0, 0, 1);
                p2 = (Point) v.getTag();
                if (p1.getX() == p2.getX() && p1.getY() == p2.getY()) {
                    unSelected(p1);
                }
                isPoint = true;
            }
            isFind = false;
            if (p2.getX()>= 0 && p2.getY()>=0) {
                if (((p1.getX() - p2.getX() == 1 || p1.getX() - p2.getX() == -1) && p1.getY() == p2.getY()) ||
                        (p1.getY() - p2.getY() == 1 || p1.getY() - p2.getY() == -1) && p1.getX() == p2.getX()) {
                    swapMap(p1.getX(), p1.getY(), p2.getX(), p2.getY());
                    swapImage();
                    if(find()){
                        step--;
                        isFind = true;
                    }
                    new Thread(Myrun).start();
                } else {
                    unSelected(p1);
                    p1 = new Point(-2, -2);
                    p2 = new Point(-2, -2);
                }
            }
        }
    };
    //重写run方法
    Runnable Myrun = new Runnable() {

        public void run() {
            if (isFind) {
                mHandler.sendEmptyMessage(BLOCK_RESTORE);//金边去掉
                mHandler.sendEmptyMessage(STEP_UPDATE);//步数更新
                wait1(100);
                //mark不为0和2的色块爆炸
                mHandler.sendEmptyMessage(BLOCK_BOOM);
                wait1(200);
                //更新state
                mHandler.sendEmptyMessage(BLOCK_UPDATE);
//                wait1(100);
//                mHandler.sendEmptyMessage(BLOCK_CLEAN);
                p1 = new Point(-2, -2);
                p2 = new Point(-2, -2);
                if (!check()) {
                    //整体重新刷新
                    int temp = score;
                    mHandler.sendEmptyMessage(BLOCK_REFRESH);
                    score = temp;
                }
//                totalStep = step;

                mHandler.sendEmptyMessage(STEP_OVER);


            }  else {
                swapMap(p1.getX(), p1.getY(), p2.getX(), p2.getY());
                wait1(100);
                //将色块换回去
                mHandler.sendEmptyMessage(BLOCK_EXCHANGE);
            }
        }
    };
    //主要接受子线程发送的数据， 并用此数据配合主线程更新UI
    public Handler mHandler = new Handler() {
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case BLOCK_BOOM: {
                    boomBtn();
                    break;
                }
                case BLOCK_UPDATE: {//把地图补充全
                    updateState();
                    text.setText("分数:   " + ((Integer) score).toString());
                    if(find()){
                        new Thread(Myrun).start();
                    }
                    break;
                }
                case BLOCK_EXCHANGE: {
                    swapImage();
                    unSelected(p1);
                    p1 = new Point(-2, -2);
                    p2 = new Point(-2, -2);
                    break;
                }
                case BLOCK_REFRESH: {
                    //显示提示
                    Toast.makeText(Game2Activity.this, "已自动生成新地图", Toast.LENGTH_SHORT).show();
                    for (int i = 0; i < 8; i++) {
                        for (int j = 0; j < 8; j++) {
                            initBtn(i, j);
                        }
                    }
                    while (find()) {
                        updateState();
                    }
                    break;
                }
                case BLOCK_RESTORE: {
                    unSelected(p1);
                    unSelected(p2);
                    break;
                }
                case STEP_UPDATE: {
                    //实行有效步骤后刷新步数

                    stepText.setText("剩余步数:   " + ((Integer) step).toString());
                    break;

                }
                case STEP_OVER: {
                    //判断步数是否到达
                    if(step==0 && !find()){
                        mySoundPool.play(gameoverMusic, 1, 1, 0, 0, 1);
                        //将本局得分插入数据库
                        UserPoint userPoint = new UserPoint();
                        UserInfo userInfo = dbManager.queryAll();
                        userPoint.setStep_point(Game2Activity.score);
                        userPoint.setUser_id(userInfo.get_id());
                        dbManager.addUserPoint(userPoint);

                        new AlertDialog.Builder(Game2Activity.this).
                                setTitle("游戏结束！").setMessage("得分:"+score)
                                .setCancelable(false)
                                .setPositiveButton("回到主界面",new DialogInterface.OnClickListener(){
                                    @Override
                                    public void onClick(DialogInterface dialog, int which) {
                                        Intent i = new Intent(Game2Activity.this,MainActivity.class);
                                        startActivity(i);
                                        Game2Activity.this.finish();
                                    }})
                                .setNegativeButton("查看排行榜", new DialogInterface.OnClickListener() {
                                    @Override
                                    public void onClick(DialogInterface dialog, int which) {

                                        Intent i = new Intent(Game2Activity.this,RankActivity.class);
                                        startActivity(i);
                                        Game2Activity.this.finish();
                                    }
                                })
                                .show();
                    }else {
                        break;
                    }

                }
            }
            super.handleMessage(msg);
        }
    };
    //倒计时对话框功能
    private void initDialog()
    {
        myDialog= new AlertDialog.Builder(this)
                .setTitle(" 游戏即将开始!")
                .setCancelable(false)
                .setView(myTextView)
                .create();
        myDialog.show();
        //用于倒计时通信
        clockHandler = new Handler() {
            public void handleMessage(Message msg) {
                if(msg.what>0){
                    myTextView.setText(String.valueOf(msg.what));
                }else {
                    if(myDialog!=null){
                        myDialog.dismiss();
                    }
                    myTimer.cancel();
                }
                super.handleMessage(msg);
            }

        };
        //实现倒计时
        myTimer = new Timer(true);
        TimerTask tt = new TimerTask() {
            //倒计时3秒，1秒后显示
            int countTime = 4;
            @Override
            public void run() {
                if (countTime > 0) {
                    countTime--;
                }
                Message msg = new Message();
                msg.what = countTime;
                clockHandler.sendMessage(msg);

            }
        };
        //1秒后显示，每1秒刷新一次
        myTimer.schedule(tt,1000,1000);
    }

    private void initMusic()
    {
        if(Build.VERSION.SDK_INT>=21)
        {
            SoundPool.Builder builder=new SoundPool.Builder();
            builder.setMaxStreams(6);
            AudioAttributes.Builder attrBuilder=new AudioAttributes.Builder();
            attrBuilder.setLegacyStreamType(AudioManager.STREAM_MUSIC);
            builder.setAudioAttributes(attrBuilder.build());
            mySoundPool=builder.build();
            buttonMusic = mySoundPool.load(this, R.raw.button,1);
            boomMusic = mySoundPool.load(this,R.raw.boom,1);
            gameoverMusic = mySoundPool.load(this,R.raw.gameover,1);
        }
        else
        {
            mySoundPool=new SoundPool(6,AudioManager.STREAM_MUSIC,0);
            buttonMusic = mySoundPool.load(this,R.raw.button,1);
            boomMusic = mySoundPool.load(this,R.raw.boom,1);
            gameoverMusic = mySoundPool.load(this,R.raw.gameover,1);

        }

    }

}
